/*
 * @Date         : 2024-05-11 17:04:41 星期6
 * @Author       : xut
 * @Description  :
 */
import grpc from "@grpc/grpc-js"
import protoLoader from "@grpc/proto-loader"
import { promisify } from "node:util"
import { resolve, dirname } from "node:path"
import { fileURLToPath } from "node:url"

const __dirname = dirname(fileURLToPath(import.meta.url))

const PROTO_PATH = resolve(__dirname, "./helloworld.proto")

const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
})

const protoDescriptor = grpc.loadPackageDefinition(packageDefinition)
const helloProto = protoDescriptor.helloworld // helloworld 为 proto 中 package 字段定义的包名

async function main() {
  /**
   * rpc 远程过程调用，像调用本地方法一样。
   * Helloworld 包中 Greeter 服务，new 一个对象 stub 放在本地，然后调用里面的方法
   */
  const client = new helloProto.Greeter(
    "localhost:50051", // Greeter 服务所在的地址
    grpc.credentials.createInsecure() // 以何种方式通信，insecure 明文通信，要启用 ssl/tls，应该用 createSsl() 传入证书
  )

  // 方式一：回调形式
  client.sayHello({ name: "tom" }, function (err, res) {
    console.log("Greeting: ", res.message)
  })

  // 方式二：await 暂不支持，见 https://github.com/grpc/grpc-node/issues/54
  // const response = await client.sayHello({ name: "tom" })

  // 方式三： 临时方案：可以使用 utils/promisify 包一下
  const sayHello = promisify(client.sayHello).bind(client)
  const res = await sayHello({ name: "tom promise" })
  console.log("Greeting: ", res.message)
}

main()
